page.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. 'use server';
  2. import './style.scss';
  3. import View from './view';
  4. import { notFound, forbidden, redirect } from 'next/navigation';
  5. import { BoardLayout, BoardSort, PostSearchType } from '@/constants/forum';
  6. import { BoardPostsRequest } from '@/types/request/forum/board';
  7. import { checkAuthServer } from '@/lib/api/auth';
  8. import { fetchBoard, fetchBoardPosts } from '@/lib/api/forum/board';
  9. import { throwError, checkPermission } from '@/lib/utils/server';
  10. import PermissionDenied from '../_component/PermissionDenied';
  11. type Props = {
  12. params: Promise<{
  13. code: string;
  14. }>;
  15. searchParams: Promise<{
  16. page: number;
  17. perPage: number;
  18. prefix?: number;
  19. sort?: BoardSort;
  20. search: PostSearchType;
  21. keyword?: string;
  22. }>;
  23. }
  24. export default async function Board({ params, searchParams }: Props)
  25. {
  26. const { code } = await params;
  27. if (!code) {
  28. return notFound();
  29. }
  30. const query = await searchParams;
  31. // 게시판 조회
  32. const board = await fetchBoard(code);
  33. if (!board || !board.data) {
  34. return notFound();
  35. }
  36. if (!board.data.isActive) {
  37. return forbidden();
  38. }
  39. if (!board.data.boardMeta) {
  40. throw new Error('게시판 속성을 찾을 수 없습니다.');
  41. }
  42. // 1:1 게시판은 로그인한 사용자만 접근 가능
  43. if (board.data.boardMeta.list.layout === BoardLayout.QnA && !await checkAuthServer()) {
  44. redirect('/login');
  45. }
  46. // 게시판 접근 권한 확인
  47. if (!await checkPermission(board.data.boardMeta.permission.boardAccess, board.data.boardManager)) {
  48. return <PermissionDenied _board={board.data} />;
  49. }
  50. query.page = Math.max(Number(query.page) || 1) as number;
  51. query.perPage = Math.max(Number(query.perPage) || (board.data.boardMeta.list.perPage || 10)) as number;
  52. query.prefix = (Number(query.prefix) || null) as number|undefined;
  53. query.sort = (Number(query.sort) || board.data.boardMeta.list.sort) as BoardSort|undefined;
  54. query.search = (Number(query.search) || PostSearchType.Subject) as PostSearchType;
  55. query.keyword = (query.keyword || '') as string|undefined;
  56. // 게시글 조회
  57. const boardPosts = await fetchBoardPosts({
  58. boardID: board.data.id as number,
  59. boardCode: board.data.code as string,
  60. page: query.page as number,
  61. perPage: query.perPage as number,
  62. boardPrefixID: query.prefix as number|null|undefined,
  63. sort: query.sort as BoardSort|null|undefined,
  64. search: query.search as PostSearchType,
  65. keyword: query.keyword as string|null|undefined
  66. } as BoardPostsRequest);
  67. if (!boardPosts.success) {
  68. throwError(boardPosts);
  69. }
  70. return (
  71. <View _query={query} _board={board.data} _postList={boardPosts.data!} />
  72. );
  73. }